/**
 *****************************************************************************
 * @file
 * @brief
 * @author taoye
 * @version V0.0.1
 * @date 2021/08/24
 ****************************************************************************
 */
 
  /* Includes ------------------------------------------------------------------*/
#include "drv_f4_gpio.h"
/* Private defines -----------------------------------------------------------*/


/* Private Struct  -----------------------------------------------------------*/


/* Private enum    -----------------------------------------------------------*/


/* Private Variable  ---------------------------------------------------------*/

/***********************************************************************************
 * @brief   
 * ex:      
 * @par      
 * None
 * @retval void None
 **********************************************************************************/
static void Gpio_Write(drv_gpio_t *this, uint8_t data)
{
    GPIO_WriteBit(this->private.port, this->private.pin, (BitAction)data);
}
/***********************************************************************************
 * @brief   
 * ex:      
 * @par      
 * None
 * @retval void None
 **********************************************************************************/
static uint8_t Gpio_Read(drv_gpio_t *this)
{
    return GPIO_ReadInputDataBit(this->private.port, this->private.pin);
} 
/***********************************************************************************
 * @brief   
 * ex:      
 * @par      
 * None
 * @retval void None
 **********************************************************************************/
int Drv_Gpio_Init(drv_gpio_t *this)
{
    GPIO_TypeDef *      port;
    uint16_t            pin;
    uint32_t            portrcc;
    uint8_t             source;

    if(this->PIN == NULL){
        return 0;
    }
    if(Common_CheckGpio(this->PIN, &port, &pin, &portrcc, &source) < 0){
        return -1;
    }

    this->Write         = Gpio_Write;
    this->Read          = Gpio_Read;
    this->private.port  = port;
    this->private.pin   = pin;

    /* 使能外设的时钟 */
    RCC_AHB1PeriphClockCmd(portrcc, ENABLE);
    /* 管脚初始化 */
    GPIO_InitTypeDef  GPIO_InitStructure;

    switch(this->MODE)
    {
        case    INPUT_UP:
            GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_IN;
            GPIO_InitStructure.GPIO_PuPd    = GPIO_PuPd_UP;
            GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_100MHz;
        break;

        case    INPUT_DOWN:
            GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_IN;
            GPIO_InitStructure.GPIO_PuPd    = GPIO_PuPd_DOWN;
            GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_100MHz;
        break;

        case    OUTPUT_UP:
            GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_OUT;
            GPIO_InitStructure.GPIO_PuPd    = GPIO_PuPd_UP;
            GPIO_InitStructure.GPIO_OType   = GPIO_OType_PP;
            GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_100MHz;
        break;

        case    OUTPUT_DOWN:
            GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_OUT;
            GPIO_InitStructure.GPIO_PuPd    = GPIO_PuPd_DOWN;
            GPIO_InitStructure.GPIO_OType   = GPIO_OType_PP;
            GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_100MHz;
        break;

        case    ANALOG_MODE:
            GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_AN;
            GPIO_InitStructure.GPIO_PuPd    = GPIO_PuPd_NOPULL;
        break;
    }

    GPIO_InitStructure.GPIO_Pin = this->private.pin;
    GPIO_Init(this->private.port, &GPIO_InitStructure);
    
    if(this->INIT_LEVEL != NULL_LEVEL){
        GPIO_WriteBit(this->private.port, this->private.pin, (BitAction)this->INIT_LEVEL);
    }
    
    return 0;
}


